package br.com.halyson.pontoeletronico.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import br.com.halyson.pontoeletronico.dao.DataHelper;
import br.com.halyson.pontoeletronico.model.Nota;
import br.com.halyson.pontoeletronico.model.Ponto;
import br.com.halyson.pontoeletronico.model.PontoDia;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteStatement;
import android.os.Environment;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;

public class Utils
{
    private static final String TAG = "Utils";
    
    private DataHelper db;
    
    public static void copyDataBaseToSD(Context context)
    {
        Log.i(TAG, "CopyDataBaseToSD ");
        
        try
        {
            File sd = Environment.getExternalStorageDirectory();
            File data = Environment.getDataDirectory();
            
            if (sd.canWrite())
            {
                String currentDBPath = "//data//" + context.getPackageName() + "//databases//" + DataHelper.DATABASE_NAME;
                String backupDBPath = DataHelper.DATABASE_NAME;
                File currentDB = new File(data, currentDBPath);
                File backupDB = new File(sd, backupDBPath);
                
                copyFile(currentDB, backupDB);
                
                Toast.makeText(context, backupDB.toString(), Toast.LENGTH_LONG).show();
            }
        }
        catch (Exception e)
        {
            Log.e(TAG, "Erro ao copiar o banco!", e);
        }
    }
    
    private static void copyFile(File fileSrc, File fileDst) throws IOException
    {
        FileChannel src = new FileInputStream(fileSrc).getChannel();
        FileChannel dst = new FileOutputStream(fileDst).getChannel();
        dst.transferFrom(src, 0, src.size());
        src.close();
        dst.close();
    }
    
    public static void restoreDataBaseFromSD(Context context)
    {
        File sd = Environment.getExternalStorageDirectory();
        
        File sdcardDbFile = new File(sd, "/ponto.db");
        
        if (!sdcardDbFile.exists())
        {
            Log.e(TAG, "O arquivo não existe!");
            Toast.makeText(context,
                "Regras:\n1 - O arquivo do banco deve ter o nome: ponto.db;\n2 - Ele deve ficar na raiz do sdcard: "
                        + Environment.getExternalStorageDirectory().getAbsolutePath() + ".",
                Toast.LENGTH_LONG).show();
            return;
        }
        
        if (!isDatabaseIntegrityOk(sdcardDbFile.getAbsolutePath()))
        {
            Log.e(TAG, "O arquivo está corrompido!");
            Toast.makeText(context, "O arquivo está corrompido!", Toast.LENGTH_LONG).show();
            return;
        }
        
        try
        {
            if (sd.canWrite())
            {
                File data = Environment.getDataDirectory();
                String dataDbPath = "//data//" + context.getPackageName() + "//databases//" + DataHelper.DATABASE_NAME;
                File dataDbFile = new File(data, dataDbPath);
                
                copyFile(sdcardDbFile, dataDbFile);
                
                Toast.makeText(context, "O banco foi restaurado com sucesso!", Toast.LENGTH_LONG).show();
            }
        }
        catch (Exception e)
        {
            Log.e(TAG, "Erro ao copiar o banco!", e);
        }
    }
    
    private static boolean isDatabaseIntegrityOk(String path)
    {
        SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        
        List<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
        attachedDbs.add(new Pair<String, String>("main", path));
        for (int i = 0; i < attachedDbs.size(); i++)
        {
            Pair<String, String> p = attachedDbs.get(i);
            SQLiteStatement prog = null;
            try
            {
                prog = db.compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
                String rslt = prog.simpleQueryForString();
                if (!rslt.equalsIgnoreCase("ok"))
                {
                    // integrity_checker failed on main or attached databases
                    Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
                    return false;
                }
            }
            finally
            {
                if (prog != null) prog.close();
                if (db != null && db.isOpen()) db.close();
            }
        }
        return true;
    }
    
    public String getCurrentTimeHour()
    {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        return String.valueOf(hour);
    }
    
    public String getCurrentTimeMinute()
    {
        Calendar calendar = Calendar.getInstance();
        int minute = calendar.get(Calendar.MINUTE);
        
        if (minute <= 9)
        {
            return String.valueOf("0" + minute);
        }
        else
        {
            return String.valueOf(minute);
        }
    }
    
    public String getCurrentDateDay()
    {
        Calendar calendar = Calendar.getInstance();
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        return String.valueOf(day);
    }
    
    public String getCurrentDateYear()
    {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        return String.valueOf(year);
    }
    
    public String getCurrentDateMonth()
    {
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        return String.valueOf(month);
    }
    
    public String getCurrentDateDayExtensive()
    {
        
        String dayWeek[] =
            new String[] { "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sabádo", "Domingo" };
        
        Calendar calendar = Calendar.getInstance();
        int dayExtensive = (calendar.get(Calendar.DAY_OF_WEEK) - 2);
        
        return String.valueOf(dayWeek[dayExtensive]);
    }
    
    public String getConvertMothsToExtensive()
    {
        String MothWeek[] =
            new String[] { "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro",
                    "Novembro", "Dezembro" };
        
        return String.valueOf(MothWeek[Integer.valueOf(getCurrentDateMonth())]);
    }
    
    public void insertPonto(String status, Context ctx)
    {
        Ponto ponto = new Ponto();
        ponto.setDayExtensive(getCurrentDateDayExtensive());
        ponto.setDia(getCurrentDateDay());
        ponto.setMes(getCurrentDateMonth());
        ponto.setMesExtensive(getConvertMothsToExtensive());
        ponto.setAno(getCurrentDateYear());
        ponto.setHora(getCurrentTimeHour() + ":" + getCurrentTimeMinute());
        ponto.setStatus(status);
        
        db = new DataHelper(ctx);
        db.insertPonto(ponto);
        
        Log.i(TAG, "insertPonto: " + ponto.toString());
        
    }
    
    public void insertNota(String nota, Context ctx)
    {
        Nota acessNota = new Nota();
        acessNota.setData(getCurrentDateDay() + "." + getCurrentDateMonth() + "." + getCurrentDateYear());
        acessNota.setMesExtensive(getConvertMothsToExtensive());
        acessNota.setAno(getCurrentDateYear());
        acessNota.setNota(nota);
        
        db = new DataHelper(ctx);
        db.insertNota(acessNota);
        
        Log.i(TAG, "insertNota: " + acessNota.toString());
        
    }
    
    public String selectNota(Context ctx)
    {
        String msg = null;
        
        db = new DataHelper(ctx);
        msg = db.selectByNoteDay(getCurrentDateDay() + "." + getCurrentDateMonth() + "." + getCurrentDateYear());
        
        Log.i(TAG, "selectNota: " + msg);
        
        return msg;
    }
}
